package de.recipeminer.models.chefkoch;

import com.google.common.collect.Sets;
import de.recipeminer.models.generic.AbstractIngredient;
import de.recipeminer.models.generic.AbstractIngredientLineItem;
import de.recipeminer.models.generic.AbstractUnit;
import de.recipeminer.models.processing.ProcessingArtifact;
import de.recipeminer.models.processing.ProcessingPhase;
import de.recipeminer.models.UniquelyIdentifiable;
import de.recipeminer.models.generic.AbstractRecipe;

import java.util.Collection;
import java.util.Collections;
import java.util.Set;

/*
@author Georg Mühlenberg
@author Markus Ackermann
@version 0.3
@date 04 Feb 2012
*/

@ProcessingArtifact(processingPhase = ProcessingPhase.EXTRACTED, aggregated = false)
public class ChefkochRecipe extends AbstractRecipe
        implements UniquelyIdentifiable {
    String uuid;
    long id, cookingTime, restingTime;
    private Set<ChefkochIngredientLineItem> ingredients = Sets.newHashSet();

    public ChefkochRecipe(String uuid, long chefkochId, String title, String instructions,
                          long preparationTime, String difficulty, long servings) {
        super(title, instructions, preparationTime, difficulty, servings);
        this.uuid = uuid;
        this.id = chefkochId;
        ingredients.addAll(ingredients);
    }

    /*public boolean addIngredientLine(ChefkochIngredient ing, float amount, ChefkochUnit unit) {
        return  ingredients.add(new ChefkochIngredientLineItem(this, ing, amount, unit));
    }*/

    public long getId() {
        return id;
    }

    @Override
    public <I extends AbstractIngredientLineItem> boolean addIngredientLineItem(I ingredientLine) {
        if (!(ingredientLine instanceof ChefkochIngredientLineItem)) {
            String msg = String.format("Can only store %s, but got %s.",
                    getClass().getName(), ingredientLine.getClass());
            throw new IllegalArgumentException(msg);
        }
        return ingredients.add((ChefkochIngredientLineItem) ingredientLine);
    }

    public ChefkochIngredientLineItem addIngredientLineItem(ChefkochIngredient ingredient, float amount,
                                                            ChefkochUnit unit) {
        if (!(ingredient instanceof ChefkochIngredient)) {
            String msg = String.format("Can only store %s, but got %s.", getClass().getName(), ingredient.getClass());
            throw new IllegalArgumentException(msg);
        }
        ChefkochIngredientLineItem lineItem = new ChefkochIngredientLineItem(this, (ChefkochIngredient) ingredient,
                amount, unit);
        boolean added = addIngredientLineItem(lineItem);
        return added ? lineItem : null;
    }


    @Override
    public Set<? extends AbstractIngredientLineItem> getIngredients() {
        return Collections.unmodifiableSet(ingredients);
    }

    public long getCookingTime() {
        return cookingTime;
    }

    public long getRestingTime() {
        return restingTime;
    }

    @Override
    public String getUUID() {
        return uuid;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        if (!super.equals(o)) return false;

        ChefkochRecipe that = (ChefkochRecipe) o;

        if (id != that.id) return false;
        if (ingredients != null ? !ingredients.equals(that.ingredients) : that.ingredients != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = super.hashCode();
        result = 31 * result + (int) (id ^ (id >>> 32));
        result = 31 * result + (ingredients != null ? ingredients.hashCode() : 0);
        return result;
    }

    public static enum Keys {
        SUBTITLE, SHOW_ID, COOKING_TIME, RESTING_TIME;
    }
}
